import * as paddleSpeech from "@/axios/paddleSpeech.js";
import * as GPT from "@/axios/GPT.js";
import * as utils from "./util";

import emitter from '@/mitt/emitter.js'
import { MetahumanEventType } from '@/mitt/MetahumanEventType.js'

import * as three3D from '@/components/three.vue'

import { reactive } from "vue";

import { startSTTWS } from "./streaSTT.js"


import ChatWsClass from '../ttsutil/chatws.js';
import ttsWsClass from '../ttsutil/ttsws.js';
import sttWsClass from '../ttsutil/sttws.js';


let temp_str = "() 好主意，但我现在要准备下午的会议资料，下次吧。"
let maxLimit = 25;
let msg = temp_str.slice(0,26);
temp_str = temp_str.slice(26,temp_str.length);


console.log(msg)
console.log(temp_str)


let a222 = {url: 'http://127.0.0.1:8787/sounds/prefix_666d2c64ea59d5.94993151.wav', msg: '好，我明白了。', phoneme_list:" Array(10)"};
let arr = [1];
arr.push(2);
console.log(arr);
console.log(arr.shift());
console.log(arr);
// let chatWs = new ChatWsClass("ws://127.0.0.1:8092/chat","be1ef32bb16f40dd90a99664337754b8","你好啊");
// console.log(chatWs);

// let chatWs = new ttsWsClass("ws://127.0.0.1:8090/tts","你好啊","MRial6V9i3C6vA2I","zhibing_emo","aly");

// let sttWs = new sttWsClass("ws://127.0.0.1:8091/stt","MRial6V9i3C6vA2I");
// sttWs.start();


let data = {'characterId':'be1ef32bb16f40dd90a99664337754b8'};



console.log(JSON.stringify(data));

let socket;
let mediaRecorder;

let socketConfig = {
  status: 0,
  audioSavePath:"F:/vue/metahuman/public/sound/",
  GptWsUrl : "ws://127.0.0.1:8000/ws",
  durTime:3000,//seconds

}

let MsgData = reactive({
  chatInputText:"", //文本后处理过的文字
  pre_text:"",  //未处理过的文字
  RepNum:0,//语音识别重复次数
  RepMaxNum:20,//语音识别最大次数，自动本次识别完成
  msgArrays: [],
  playIng:false, //音频播放中
})


// 每次会话的变量
let chatData = reactive({
  temp_timer : null,
  pre_str :"",//上次
  temp_str:"",//储存未生成语音的字符
  chatMessages:[], //{msg,soundName,duration}
  chat_id:0,//用于语音生成的id
  maxNum:15,//10个字符生成一次语音（如果有标点符号的时候）
  playIndex:0,
  chatCreated:false,//本次内容是否生成完成
  audioCreated:false,//本次音频是否生成完成
  taskIng:false, //会话是否进行中
  playAutoCallbackDuration:300, //如果音频还未生成，前面的已经播放完毕，间隔事件，循环调用后续播放
  AudioPlayAutoTimer:null
})


let a = "您可以尝试休息一下，如果头痛持续或加重，最好咨询医生。";
// testLimitStr(a)
function testLimitStr(temp_str)
{
  let limit1 =temp_str.indexOf("？");
  let limit2 =temp_str.indexOf("。");
  let limit3 =temp_str.indexOf("！");
  let limit4 =temp_str.indexOf("，");
  let maxLimit = Math.max(limit1,limit2,limit3,limit4);
  if (maxLimit >= 0 && temp_str.length > chatData.maxNum)
  {
    let msg = temp_str.slice(0,maxLimit+1);
    console.log(msg)
  }
}
// emitter.emit(MetahumanEventType.RecordingMsg, "fdfsafas");



navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    const source = audioContext.createMediaStreamSource(stream);
    const processor = audioContext.createScriptProcessor(4096, 1, 1);

    source.connect(processor);
    processor.connect(audioContext.destination);

    processor.onaudioprocess = async (e) => {
        const inputBuffer = e.inputBuffer.getChannelData(0);
        const downsampledBuffer = await utils.downsampleBuffer(inputBuffer, audioContext.sampleRate, 16000);
        const pcm16Buffer = utils.floatTo16BitPCM(downsampledBuffer);
        if(socket  && socketConfig.status == 1)
        {
          socket.send(pcm16Buffer);
        }
    };

    mediaRecorder = new MediaRecorder(stream);
    // mediaRecorder.onstop = () => {
    //     socket.close();
    // };
  });

  
// 停止本次语音会话
function stopSocket() 
{
  // let data = {
  //         "name": "test.wav",
  //         "signal": "end",
  //         "nbest": 1
  //         }



  let data =      {
    "header": {
        "message_id": "05450bf69c53413f8d88aed1ee601234",
        "task_id": "640bc797bb684bd69601856513071234",
        "namespace": "SpeechTranscriber",
        "name": "StopTranscription",
        "appkey": "MRial6V9i3C6vA2I"
    }
}

  socket.send(JSON.stringify(data));
  mediaRecorder.stop();
  // sendMsg();
  socket.close();
  console.log("语音识别完成")
  chatData.chatCreated = true;
}


function startSTT()
{
  // let data = {
  //   "name": "test.wav",
  //   "signal": "start",
  //   "nbest": 1
  // }

  let data =      {
    "header": {
        "message_id": "05450bf69c53413f8d88aed1ee601234",
        "task_id": "640bc797bb684bd69601856513071234",
        "namespace": "SpeechTranscriber",
        "name": "StartTranscription",
        "appkey": "MRial6V9i3C6vA2I"
    },
    "payload": {
        "format": "PCM",
        "sample_rate": 16000,
        "enable_intermediate_result": true,
        "enable_punctuation_prediction": true,
        "enable_inverse_text_normalization": true
    }
}
  socket.send(JSON.stringify(data));

  console.log("语音开始识别")
  chatData.chatCreated = false;

  chatData.taskIng = true;


}

function STTSocketMessage(event)
{
  let message = JSON.parse(event.data);
  let text = message.result;
  if(text == "" || text == undefined || !text) return false;
  if(MsgData.pre_text != text )
  {
    MsgData.pre_text  = text;
    MsgData.RepNum = 0;
    // 处理文本标点符号
    paddleSpeech.punctuation({text: MsgData.pre_text})
      .then(res => {
        MsgData.chatInputText = res.result.punc_text;
      })
      .catch(error => {
        console.error('Error:', error);
      });
  }else{
    MsgData.RepNum++
    if(MsgData.RepNum >= MsgData.RepMaxNum)
    {
      stopSocket();
    }
  }
}
  
function initSocket()
{

  // startSTTWS();
  // return;
  // socket = new WebSocket('ws://127.0.0.1:8091/paddlespeech/asr/streaming');
  socket = new WebSocket('ws://127.0.0.1:8091/stt');
  // socket = new WebSocket('wss://nls-gateway.aliyuncs.com/ws/v1?token=c79f6e32ebdb445cad25d74611b8b489');
 
  socket.binaryType = 'arraybuffer';
  socket.onopen = () => {
    // startSTT();
  };
  socket.onmessage = event => {
    // console.log(event);
    let message = JSON.parse(event.data);

    if(message.header)
    {
      let eventName  = message.header.name;
      console.log(eventName);

      switch(eventName)
      {
        case "TranscriptionStarted":
          socketConfig.status =  1;
          mediaRecorder.start();
          break;
        case "TranscriptionResultChanged":
          console.log(message.payload.result);
          if(chatData.temp_timer) clearTimeout(chatData.temp_timer);
          console.log(message.payload.result);
          break;
        case "SentenceEnd":
          console.log(message.payload.result);
          if(chatData.temp_timer) clearTimeout(chatData.temp_timer);
          chatData.temp_timer = setTimeout(() =>{
            socketConfig.status =  0;
            stopSocket();
          },socketConfig.durTime)
          break;
        case "TranscriptionCompleted":
          console.log("本次识别结束");
          socketConfig.status =  0;
          break;

      }
    }else if(message.status && message.status == 'success')
    {
      startSTT();
    }

    // STTSocketMessage(event)
  };

  socket.onclose = () => {
    socketConfig.status =  0;
  };


  // setTimeout(() =>{
  //   stopSocket();
  // },5000)
}






// 发送信息
function sendMsg()
{

  if(MsgData.chatInputText == "") return;
  resetInfo();
  chatData.audioCreated = false;
  emitter.emit(MetahumanEventType.UserSendMsg, MsgData.chatInputText);
  // 开启本次监听
  utils.createChatWsSocket(socketConfig.GptWsUrl,(res)=>{
    let resJSON = JSON.parse(res.data);
    chatData.temp_str += resJSON.msg

    // 最后一条音频生成
    if( resJSON.finish_reason == "stop")
    {
      if(chatData.temp_str != "")
      {
        let soundName =  "chat"+chatData.chat_id+".wav";
        let temp_chatObj = {
          msg : chatData.temp_str,
          soundName: soundName
        }
        createChatAudio(temp_chatObj,chatData.chat_id, true);
      }else{
        chatData.audioCreated = true;
      }
      utils.closeChatWs();
    }
    else
    {
      let limit1 = chatData.temp_str.indexOf("？");
      let limit2 = chatData.temp_str.indexOf("。");
      let limit3 = chatData.temp_str.indexOf("！");
      let limit4 = chatData.temp_str.indexOf("，");
      let maxLimit = Math.max(limit1,limit2,limit3,limit4);
      if (maxLimit >= 0 && chatData.temp_str.length > chatData.maxNum)
      {
        let msg = chatData.temp_str.slice(0,maxLimit+1);
        let soundName =  "chat"+chatData.chat_id+".wav";
        let temp_chatObj = {
          msg : msg,
          soundName: soundName,
        }
        createChatAudio(temp_chatObj,chatData.chat_id)
        chatData.temp_str = chatData.temp_str.slice(maxLimit+1,chatData.temp_str.length);
      }
    }
  })
  GPT.getGptMsg({content:MsgData.chatInputText})
  MsgData.chatInputText = "";
}





// 生成语音
function createChatAudio(temp_chatObj,index,audioCreated)
{
  chatData.chat_id++;
  GPT.tts({
    "text": temp_chatObj.msg,
    "save_path": socketConfig.audioSavePath + temp_chatObj.soundName
  }).then((res)=>{
    if(res && res.metadata && res.mouthCues)
    {
      temp_chatObj.duration = res.metadata.duration;
      temp_chatObj.mouthCues =  res.mouthCues;
      chatData.chatMessages[index] = temp_chatObj;

      console.log(chatData.chatMessages)
      // 第一句话合成完毕，就播放
      if(index == 0)
      {
        playAudio()
        MsgData.playIng = true;
        emitter.emit(MetahumanEventType.ChatSendMsg, "");

      }
      // 确保所有音频合成完毕
      if(audioCreated)
      {
        chatData.audioCreated = audioCreated;
      }
    }
  }).catch((err)=>{
    console.log(err)
  });
 
}



function playAudio() 
{
  if(!chatData.chatMessages[chatData.playIndex]) return false;
  if(chatData.AudioPlayAutoTimer) 
  {
    clearInterval(chatData.AudioPlayAutoTimer);
  }
  let audioObj = chatData.chatMessages[chatData.playIndex]
  let audioUrl = "/sound/"+audioObj.soundName;
  const audio = new Audio(audioUrl+"?="+Math.random()); // 替换为你的音频文件路径
  audio.play();

  // 播放口型动画
  emitter.emit(MetahumanEventType.BodyAnimation,"Talk");
  const syncData = audioObj.mouthCues;

  let oldMessage = "";
  for(let i=0; i<chatData.playIndex; i++)
  {
    oldMessage += chatData.chatMessages[i].msg;
  }

  audio.addEventListener('timeupdate', function() {
    const  currentAudioTime = audio.currentTime;
    const progress = audio.currentTime / audioObj.duration;
    let strLen = Math.round(progress * audioObj.msg.length);
    let current_msg = audioObj.msg.slice(0,strLen);
    let fullMsg = oldMessage+current_msg;

    emitter.emit(MetahumanEventType.ChatSendMsgIng,fullMsg);

    for (let i=0; i<syncData.length; i++) 
    {
      let sync = syncData[i];
      if(currentAudioTime >= sync.start && currentAudioTime < sync.end)
      {
        emitter.emit(MetahumanEventType.LipSyncAnimation,sync.value);
        break;
      }
    }
   

  });
  // 监听播放结束
  audio.addEventListener('ended', function() {
    // 要判断是否已经播放完毕，要考虑到后续的音频是否太长还未生成完成
    if(chatData.playIndex < chatData.chatMessages.length - 1)
    {
      chatData.playIndex++;
      playAudio();
    }else{

      console.log("chatData.audioCreated:"+chatData.audioCreated);
      if(chatData.chatCreated && chatData.audioCreated)
      {
        console.log("本次会话音频内容播放完毕")
        MsgData.playIng = false;
        chatData.taskIng = false;
        emitter.emit(MetahumanEventType.LipSyncAnimation);
        emitter.emit(MetahumanEventType.BodyAnimation,"idle");
      }else{
        chatData.playIndex++;
        chatData.AudioPlayAutoTimer = setInterval(()=>{
          playAudio();
          console.log("循环调用播放")
        },chatData.playAutoCallbackDuration)
      }
    }
  });
}



// 初始化信息
function resetInfo()
{
  MsgData.pre_text = "";
  MsgData.RepNum = 0;

  // 每次会话都要初始化
  chatData.chatMessages.length = 0;
  chatData.temp_str = "";
  chatData.chat_id = 0;
  chatData.playIndex = 0;
}



function testMsg()
{
  utils.createChatWsSocket(socketConfig.GptWsUrl,(res)=>{
    let resJSON = JSON.parse(res.data);
    console.log(resJSON.msg)

    chatData.temp_str += resJSON.msg
    if ((chatData.temp_str == "，" || chatData.temp_str == "。") && chatData.temp_str.length > chatData.maxNum)
    {
      let temp_chatObj = {
        msg : chatData.temp_str,
        soundName: "chat"+chatData.chat_id+".wav"
      }
      createChatAudio(temp_chatObj)
    }
    if( resJSON.finish_reason == "stop")
    {
      if(chatData.temp_str != "")
      {
        let temp_chatObj = {
          msg : chatData.temp_str,
          soundName: "chat"+chatData.chat_id+".wav"
        }
        createChatAudio(temp_chatObj)
      }
      utils.closeChatWs();
    }
  })
  GPT.getGptMsg({content:"你好"})
}

export { initSocket , sendMsg , socketConfig , MsgData , chatData}